package com.ivanceras.shared.meta;

import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

import com.ivanceras.server.db.EMF;
import com.ivanceras.server.util.CStringUtils;
import com.ivanceras.shared.dao.DAO_Krn_attribute;
import com.ivanceras.shared.dao.DAO_Krn_hasone;
import com.ivanceras.shared.dao.DAO_Krn_model;
import com.ivanceras.shared.db.DAO;
import com.ivanceras.shared.db.EntityManager;
import com.ivanceras.shared.db.IModelDef;
import com.ivanceras.shared.exception.DatabaseException;
import com.ivanceras.shared.exception.ModelDefinitionNotFoundException;

public class ModelDefinitionProvider {

	private static ModelMetaData metadata = new ModelMetaData();

	public static IModelDef getDefinition(String modelName) throws ModelDefinitionNotFoundException{
		HashMap<String, IModelDef> modeldefList = metadata.modelDefList;
		if(modeldefList.containsKey(modelName)){
			IModelDef modeldef = modeldefList.get(modelName);
			return modeldef;
		}else{
			throw new ModelDefinitionNotFoundException("No model definition found for ["+modelName+"]");
		}
	}

	public static void saveMetaData(IModelDef model) throws DatabaseException{
		EntityManager em = null;
		try{
			em = EMF.get();
			em.beginTransaction();
			DAO_Krn_model krnModel = toKrnModel(model);
			DAO_Krn_model nkrnModel = DAO_Krn_model.cast(em.insert(krnModel));
			DAO_Krn_attribute[] krnAttributeList = krnModel.getKrn_attributeList();
			for(DAO_Krn_attribute att : krnAttributeList){
				att.setKrn_model_id(nkrnModel.getKrn_model_id());
				em.insert(att);
			}
			DAO_Krn_hasone[] hasOneList = krnModel.getKrn_hasoneList();
			for(DAO_Krn_hasone hasOne : hasOneList){
				hasOne.setKrn_model_id(nkrnModel.getKrn_model_id());
				em.insert(hasOne);
			}
			em.commitTransaction();
		}catch(DatabaseException e){
			e.printStackTrace();
			try {
				em.rollbackTransaction();
			} catch (DatabaseException e1) {
				e1.printStackTrace();
				throw new DatabaseException("Unable to rollback transaction");
			}
			throw new DatabaseException();
		}
	}

	private static DAO_Krn_model toKrnModel(IModelDef model){
		DAO_Krn_model krnModel = new DAO_Krn_model();
		krnModel.setNamespace(model.getNamespace());
		String[] attributes = model.getAttributes();
		String[] primaryAttributes = model.getPrimaryAttributes();
		String[] uniqueAttributes = model.getUniqueAttributes();
		String[] dataTypes = model.getDataTypes();
		String generatedAttribute = model.getGeneratedAttribute();
		krnModel.setGeneratedattribute(generatedAttribute);
		krnModel.setKrn_model_uu(UUID.randomUUID().toString());

		DAO_Krn_attribute[] krnAttributeList = new DAO_Krn_attribute[attributes.length];
		for(int i = 0; i < attributes.length; i++){
			String att = attributes[i];
			String dataType = dataTypes[i];
			DAO_Krn_attribute krn_att = new DAO_Krn_attribute();
			krn_att.setKrn_attribute_uu(UUID.randomUUID().toString());
			krn_att.setName(att);
			krn_att.setDatatype(dataType);
			krn_att.setIsactive(true);
			int pindex = CStringUtils.indexOf(primaryAttributes, att);
			if(pindex >= 0){
				krn_att.setIsprimary(true);
			}else{
				krn_att.setIsprimary(false);
			}
			int uindex = CStringUtils.indexOf(uniqueAttributes, att);
			if(uindex >= 0){
				krn_att.setIsunique(true);
			}else{
				krn_att.setIsunique(false);
			}
			krnAttributeList[i] = krn_att;
		}
		krnModel.setKrn_attributeList(krnAttributeList);
		String[] hasOneList = model.getHasOne();
		DAO_Krn_hasone[] krnHasOneList = new DAO_Krn_hasone[hasOneList.length];
		for(String hasOne : hasOneList){
			DAO_Krn_hasone krnHasOne = new DAO_Krn_hasone();
			
		}
		krnModel.setKrn_hasoneList(krnHasOneList);
		return krnModel;
	}
}
